package com.general.framework.thread;

import java.util.concurrent.atomic.AtomicInteger;


/**
 * AtomicIntegter只能确保自己本身操作具有原子性，但是多个AtomicInteger操作合起来这个是确保不了的；
 * 可以使用synchronized将多个操作包含起来，但是使用到synchronized的锁操作势必会降低一部分并发的性能
 * 这个时候就需要用到Atomic给我们提供的另外一个类了，AtomicReference
 * 它可以将多个变量封装为对象的多个属性，然后一次性的更新整个对象，就能CAS的更新多个变量，确保原子性
 */
public class AtomicIntegerMain {
    // 定义一个锁对象
    private static final Object lock = new Object();
    // 声明三个AtomicInteger的原子类
    private static AtomicInteger value1 = new AtomicInteger(0);
    private static AtomicInteger value2 = new AtomicInteger(0);
    private static AtomicInteger value3 = new AtomicInteger(0);

    // 定义一个线程，执行3个AtomicInteger的++操作
    public static class MultiUpdateThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                // 同步代码块，保证线程安全
                synchronized (lock) {
                    value1.incrementAndGet();
                    value2.incrementAndGet();
                    value3.incrementAndGet();
                    // 假如说执行完一次操作之后，出现
                    // value1、value2、value3任何两两不相等的情况 则打印报错
                    int i1 = value1.get();
                    int i2 = value2.get();
                    int i3 = value3.get();
                    if (i1 != i2 || i1 != i3 || i2 != i3) {
                        System.out.println(i1 + "--" + i2 + "--" + i3 + "  不好意思，出错了！");
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 创建两个线程，并发的操作
        MultiUpdateThread thread1 = new MultiUpdateThread();
        MultiUpdateThread thread2 = new MultiUpdateThread();

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println("运行结束了......");
    }
}
